home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1997 / MacHack 1997.toast / Hacks / Hacks ’93 / String Extractor⁄Localization / Scanner / Extract.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-19  |  5.8 KB  |  370 lines  |  [TEXT/KAHL]

  1. /*
  2.  * Extract.c
  3.  *
  4.  */
  5.  
  6. #define PSTRING "PLiteral ( %d , %d )"
  7. #define CSTRING "CLiteral ( %d , %d )"
  8.  
  9. /*
  10.  * You'll have to change MPW_INPUT to 1 and re-compile if you
  11.  * extract MPW C string literals
  12.  */
  13. #define REZ_OUTPUT 1
  14. #define MPW_INPUT 0
  15. #define EMPTY_STRING_ON_EMPTY_LIST 0
  16.  
  17. #define PRINT_SCAN 0
  18. #define PRINT_STORE 0
  19.  
  20. #include "Error.h"
  21. #include "Extract.h"
  22.  
  23. #include "stdio.h"
  24. #include "string.h"
  25.  
  26.  
  27. /*
  28.  * UGLY but necessary
  29.  */
  30.  
  31. long pos ;
  32. long end ;
  33. Handle data ;
  34. Handle output ;
  35. short theID ;
  36. short theNumber ;
  37. Boolean gotOne ;
  38.  
  39.  
  40. #define CHAR(x) ((x)>=(end)?0:(*data)[x])
  41. #define POS CHAR(pos)
  42.  
  43. #if PRINT_SCAN
  44. #define NEWPOS if(POS==13)putchar(10);else putchar(POS);fflush(stdout);pos++
  45. #else
  46. #define NEWPOS pos++
  47. #endif
  48.  
  49.  
  50. static char
  51. ReadChar ( void ) {
  52.  
  53. char theChar = POS ;
  54.  
  55.     NEWPOS ;
  56.     if ( theChar == '\\' ) {
  57.         theChar = POS ;
  58.         if ( theChar >= '0' && theChar <= '7' ) {
  59.  
  60.         int num = 0 ;
  61.         int ch = 0 ;
  62.  
  63.             while ( num < 3 && ( theChar = POS ) >= '0' && theChar <= '7' ) {
  64.                 num ++ ;
  65.                 ch <<= 3 ;
  66.                 ch += ( theChar - '0' ) ;
  67.                 NEWPOS ;
  68.             }
  69.             theChar = ch ;
  70.         } else {
  71.             NEWPOS ;
  72.             switch ( theChar ) {
  73. #if MPW_INPUT
  74. /*
  75.  * MPW is way brain-damaged for its string constants
  76.  */
  77.             case 'n' :
  78.                 theChar = 13 ;
  79.                 break ;
  80.             case 'r' :
  81.                 theChar = 10 ;
  82.                 break ;
  83. #else
  84.             case 'n' :
  85.                 theChar = 10 ;
  86.                 break ;
  87.             case 'r' :
  88.                 theChar = 13 ;
  89.                 break ;
  90. #endif
  91.             case 'b' :
  92.                 theChar = 8 ;
  93.                 break ;
  94.             case 't' :
  95.                 theChar = 9 ;
  96.                 break ;
  97.             case 'f' :
  98.                 theChar = 12 ;
  99.                 break ;
  100.             default :
  101.                 break ;
  102.             }
  103.         }
  104.     }
  105.     return theChar ;
  106. }
  107.  
  108.  
  109. static void
  110. SkipCharLiteral ( void ) {
  111.  
  112.     while ( pos < end ) {
  113.         if ( POS == '\'' ) {
  114.             NEWPOS ;
  115.             return ;
  116.         }
  117.         ( void ) ReadChar ( ) ;
  118.     }
  119. }
  120.  
  121.  
  122. static void
  123. SkipToEndOfLine ( void ) {
  124.     while ( pos < end ) {
  125.         if ( POS == '\r' || POS == '\n' ) {
  126.             NEWPOS ;
  127.             return ;
  128.         }
  129.         NEWPOS ;
  130.     }
  131. }
  132.  
  133.  
  134. static void
  135. SkipCComment ( void ) {
  136.     while ( pos < end ) {
  137.         if ( POS == '*' ) {
  138.             NEWPOS ;
  139.             if ( POS == '/' ) {
  140.                 NEWPOS ;
  141.                 return ;
  142.             }
  143.         } else {
  144.             NEWPOS ;
  145.         }
  146.     }
  147. }
  148.  
  149.  
  150. static void
  151. HaveString ( Handle string , Boolean pascalMode , long fromPos ) {
  152.  
  153. char buf [ 300 ] ;
  154. char bb [ 30 ] ;
  155. char * fromC , * endC ;
  156. unsigned char cc ;
  157.  
  158.     buf [ 0 ] = 0 ;
  159.     bb [ 0 ] = 0 ;
  160.     HLock ( string ) ;
  161.     fromC = * string ;
  162.     endC = GetHandleSize ( string ) + fromC ;
  163.     while ( fromC < endC ) {
  164.         cc = ( unsigned char ) * ( fromC ++ ) ;
  165.         switch ( cc ) {
  166.         case 0 :
  167.         case 1 :
  168.         case 2 :
  169.         case 3 :
  170.         case 4 :
  171.         case 5 :
  172.         case 6 :
  173.         case 7 :
  174.         case 11 :
  175.         case 14 :
  176.         case 15 :
  177.         case 16 :
  178.         case 17 :
  179.         case 18 :
  180.         case 19 :
  181.         case 20 :
  182.         case 21 :
  183.         case 22 :
  184.         case 23 :
  185.         case 24 :
  186.         case 25 :
  187.         case 26 :
  188.         case 27 :
  189.         case 28 :
  190.         case 29 :
  191.         case 30 :
  192.         case 31 :
  193.             sprintf ( bb , "\\%03o" , cc ) ;
  194.             strcat ( buf , bb ) ;
  195.             break ;
  196.         case 8 :
  197.             strcat ( buf , "\\b" ) ;
  198.             break ;
  199.         case 9 :
  200.             strcat ( buf , "\\t" ) ;
  201.             break ;
  202. #if REZ_OUTPUT
  203. /*
  204.  * We change these around for output because Rez is brain-damaged
  205.  */
  206.         case 10 :
  207.             strcat ( buf , "\\r" ) ;
  208.             break ;
  209.         case 13 :
  210.             strcat ( buf , "\\n" ) ;
  211.             break ;
  212. #else
  213.         case 10 :
  214.             strcat ( buf , "\\n" ) ;
  215.             break ;
  216.         case 13 :
  217.             strcat ( buf , "\\r" ) ;
  218.             break ;
  219. #endif
  220.         case 12 :
  221.             strcat ( buf , "\\f" ) ;
  222.             break ;
  223.         case '\"' :
  224.             strcat ( buf , "\\\"" ) ;
  225.             break ;
  226.         case '\\' :
  227.             strcat ( buf , "\\\\" ) ;
  228.             break ;
  229.         default :
  230.             bb [ 0 ] = cc ;
  231.             bb [ 1 ] = 0 ;
  232.             strcat ( buf , bb ) ;
  233.             break ;
  234.         }
  235.     }
  236.     PtrAndHand ( "\t\t\"" , output , 3 ) ;
  237.     PtrAndHand ( buf , output , strlen ( buf ) ) ;
  238.     PtrAndHand ( "\",\r" , output , 3 ) ;
  239.     Error ( MemError ( ) ) ;
  240.     HUnlock ( string ) ;
  241.     if ( pascalMode ) {
  242.         sprintf ( buf , PSTRING , theID , theNumber ) ;
  243.     } else {
  244.         sprintf ( buf , CSTRING , theID , theNumber ) ;
  245.     }
  246.     theNumber ++ ;
  247.     Munger ( data , fromPos , NULL , pos - fromPos , buf , strlen ( buf ) ) ;
  248.     pos = fromPos + strlen ( buf ) ;
  249.     end = GetHandleSize ( data ) ;
  250. }
  251.  
  252.  
  253. static void
  254. ReadStringLiteral ( void ) {
  255.  
  256. Handle string = NewHandle ( 0L ) ;
  257. long thatPos = pos - 1 ;
  258. char theChar ;
  259. Boolean pascalMode = 0 ;
  260.  
  261.     if ( ! string ) {
  262.         Error ( MemError ( ) ) ;
  263.     }
  264.     gotOne = 1 ;
  265.     if ( POS == '\\' && ( CHAR ( pos + 1 ) == 'P' || CHAR ( pos + 1 ) == 'p' ) ) {
  266.         pascalMode = 1 ;
  267.         NEWPOS ; NEWPOS ;
  268.     }
  269.     while ( pos < end ) {
  270.         if ( POS == '\"' ) {
  271.             NEWPOS ;
  272.             HaveString ( string , pascalMode , thatPos ) ;
  273.              DisposeHandle ( string ) ;
  274. #if PRINT_STORE
  275.             putchar ( "\r\n" ) ;
  276. #endif
  277.             return ;
  278.         }
  279.         theChar = ReadChar ( ) ;
  280. #if PRINT_STORE
  281.         putchar ( theChar ) ; fflush ( stdout ) ;
  282. #endif
  283.         PtrAndHand ( & theChar , string , 1 ) ;
  284.     }
  285.     DebugStr ( "\POoof!" ) ;
  286.     DisposeHandle ( string ) ;
  287. }
  288.  
  289.  
  290. static void
  291. ReadLine ( void ) {
  292.     while ( pos < end ) {
  293.         switch ( POS ) {
  294.  
  295.         case 0 :
  296.         case '\r' :
  297.         case '\n' :
  298.             NEWPOS ;
  299.             return ;
  300.     
  301.         case ' ' :
  302.         case '\t' :
  303.             NEWPOS ;
  304.             break ;
  305.     
  306.         case '\'' :
  307.             NEWPOS ;
  308.             SkipCharLiteral ( ) ;
  309.             break ;
  310.     
  311.         case '#' :
  312.             NEWPOS ;
  313.             SkipToEndOfLine ( ) ;
  314.             break ;
  315.  
  316.         case '/' :
  317.             NEWPOS ;
  318.             if ( POS == '*' ) {
  319.                 NEWPOS ;
  320.                 SkipCComment ( ) ;
  321.             } else if ( POS == '/' ) {
  322.                 SkipToEndOfLine ( ) ;
  323.             }
  324.             break ;
  325.  
  326.         case '\"' :
  327.             NEWPOS ;
  328.             ReadStringLiteral ( ) ;
  329.             break ;
  330.     
  331.         default :
  332.             NEWPOS ;
  333.             break ;
  334.         }
  335.     }
  336. }
  337.  
  338.  
  339. pascal short
  340. Extract ( Handle inData , Handle outData , short idBase , short numberBase ) {
  341.  
  342. char buf [ 256 ] ;
  343.  
  344.     data = inData ;
  345.     output = outData ;
  346.     pos = 0 ;
  347.     end = GetHandleSize ( inData ) ;
  348.     theID = idBase ;
  349.     theNumber = numberBase ;
  350.  
  351.     sprintf ( buf , "resource 'STR#' (%d) {\r\t{\r" , idBase ) ;
  352.     PtrAndHand ( buf , output , strlen ( buf ) ) ;
  353.     gotOne = 0 ;
  354.     while ( pos < end ) {
  355.         ReadLine ( ) ;
  356.     }
  357. #if EMPTY_STRING_ON_EMPTY_LIST
  358.     if ( ! gotOne ) {
  359.         PtrAndHand ( "\t\t\"\"\r" , output , 5 ) ;
  360.     }
  361. #endif
  362.     PtrAndHand ( "\t}\r};\r" , output , 6 ) ;
  363.  
  364.     sprintf ( buf , "\r/**ID:%04d*/\r/**NM:%04d*/\r" , idBase , theNumber - 1 ) ;
  365.     PtrAndHand ( buf , data , strlen ( buf ) ) ;
  366.  
  367.     return theNumber ;
  368. }
  369.  
  370.